package ro.upt.dcda.pricezone.common;

import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import ro.upt.dcda.pricezone.common.Config.ServerInfo;

public class JMSMediator {

	private Context context;
	private HashMap<String, Server> servers = new HashMap<>();
	private static JMSMediator mediator;

	private JMSMediator() throws NamingException, JMSException {
		Hashtable<Object, Object> properties = new Hashtable<>();
		properties.put(Context.INITIAL_CONTEXT_FACTORY,
				"org.exolab.jms.jndi.InitialContextFactory");
		properties.put(Context.PROVIDER_URL, "tcp://127.0.0.1:3035/");
		context = new InitialContext(properties);
	}

	public Collection<Server> getServers() {
		return servers.values();
	}

	private void addServer(String serverName, String outQueueName,
			String inQueueName) throws NamingException, JMSException {
		Queue outQueue = (Queue) context.lookup(outQueueName);
		Queue inQueue = (Queue) context.lookup(inQueueName);
		QueueConnectionFactory factory = (QueueConnectionFactory) context
				.lookup("JmsQueueConnectionFactory");
		QueueConnection connection = factory.createQueueConnection();
		QueueSession queueSession = connection.createQueueSession(false,
				Session.AUTO_ACKNOWLEDGE);
		connection.start();
		Server newServer = new Server(serverName,inQueue, outQueue, queueSession);
		newServer.setDaemon(true);
		newServer.start();
		servers.put(serverName, newServer);
	}

	public Server getServerByName(String serverName) {
		return servers.get(serverName);
	}

	public Server getServerByLocation(double x, double y) {
		for (ServerInfo server : Config.getServerList()) {
			if (server.getXmin() <= x && server.getXmax() >= x
					&& server.getYmin() <= y && server.getYmax() >= y) {
				System.out.println("for " + x + " " + y + " "
						+ server.getName());
				return getServerByName(server.getName());
			}
		}
		return null;
	}

	public synchronized static JMSMediator getMediator()
			throws NamingException, JMSException {
		if (mediator == null) {
			mediator = new JMSMediator();
			for (ServerInfo server : Config.getServerList()) {
				mediator.addServer(server.getName(), server.getQueue(),
						server.getQueueResp());
			}
		}
		return mediator;
	}
}
